#ifndef EMPLEADO_H_
#define EMPLEADO_H_
#include "Proceso.h"
#include "Caja.h"
#include "semaphore/Semaforo.h"
#include "signal/SIGINT_Handler.h"
#include "signal/SignalHandler.h"
#include "GeneradorRandom.h"
#include <vector>
#include "Surtidor.h"
#include "Cliente.h"
#include "Constantes.h"
#include "Utilidades.h"
#include "MensajePeticionCaja.h"
#include "msgQueue/Cola.h"

class Empleado: public Proceso {

public:
	typedef std::vector<Surtidor> Surtidores;
	typedef std::vector<Semaforo> Semaforos;

	Empleado(
			int id,
			const string& nombreProceso,
			Surtidores& surtidores,
			Semaforos& semaforos,
			bool logActivo,
			int nEmpleado,
			int cantEmpleados);

	virtual ~Empleado();
	// Constructor copia
	Empleado(const Empleado& otro);
	// Funcionalidad completa de un empleado del sistema
	Empleado& operator=(const Empleado& otro);
	void run();
	void eliminar();
	int getId();

	/* Devuelve si esta o no liber el surtidor de la posicion pos*/
	bool es_surtidor_libre(unsigned int pos);
	/* Proceso de buscado de un surtidor libre. Se busca y se ocupa uno */
	int buscar_surtidor();
	/*Toma el surtidor de la posicion pos */
	bool tomar_surtidor(const unsigned int pos);
	/*Libera el surtidor de la posicion pos */
	int liberar_surtidor(const unsigned int pos);
	/*Ocupa el surtidor de la posicion pos */
	bool ocupar_surtidor(unsigned int pos);
	/*Proceso de carga de nafta al cliente*/
	void cargar_nafta();
	Semaforo& getSemaforoPeticionCaja();
	int getPrioridadCaja() const;
private:
	// Obtiene el acceso a la caja, acumula dinero y libera la caja
	void cobrar_y_guardar_en_caja(Cliente& c);
	// Simula el tiempo que se tarda en atender al cliente
	void atender_cliente(Cliente& c);
	void finalizar_operacion();
	// Obtiene el cliente de la memoria compartida con el jefe
	int recibir_cliente(Cliente& c);


private:
	Caja caja_; // Caja compartida donde se guarda el dinero
	Semaforo semaforoUtilizandoCaja; // Semaforo para proteger el uso de la caja
	Semaforo semaforoPeticionCaja; // Semaforo donde se queda bloqueado al querer usar la caja
	const int prioridadCaja;
	Cola<MensajePeticionCaja> colaMensajesCaja;
	int id_; // Identificador del empleado
	Surtidores surtidores_;
	Semaforos semaforos_;
	MemoriaCompartida<Cliente> memoria_clientes_;
	MemoriaCompartida<bool> empleados_ocupados_;
	Semaforo acceder_memoria_clientes_;
	Semaforo estado_empleado_;
	int numero_empleado_;

};

#endif /* EMPLEADO_H_ */
